---
title: unstable_after (experimental)
description: API Reference for the unstable_after function.
---

> This API is **experimental** and subject to change.

`unstable_after()` allows you to schedule work to be executed after a response is finished. This is useful for tasks and other side effects that should not block the response, such as logging and analytics.

It can be used in [Server Components](/docs/app/building-your-application/rendering/server-components) (including [`generateMetadata`](https://nextjs.org/docs/app/api-reference/functions/generate-metadata)), [Server Actions](/docs/app/building-your-application/data-fetching/server-actions-and-mutations), [Route Handlers](/docs/app/building-your-application/routing/route-handlers), and [Middleware](/docs/app/building-your-application/routing/middleware).

To use `unstable_after()`, you need to enable it using the `experimental.after` config in the `next.config.js` file:

```js filename="next.config.js"
const nextConfig = {
  experimental: {
    after: true,
  },
}
module.exports = nextConfig
```

The function accepts a callback that will be executed after the response is finished:

```tsx filename="app/layout.tsx switcher
import { unstable_after as after } from 'next/server'
import { log } from '@/app/utils'

export default function Layout({ children }: { children: React.ReactNode }) {
  after(() => {
    // Execute after the layout is rendered and sent to the user
    log()
  })
  return <>{children}</>
}
```

```jsx filename="app/layout.js switcher
import { unstable_after as after } from 'next/server'
import { log } from '@/app/utils'

export default function Layout({ children }) {
  after(() => {
    // Execute after the layout is rendered and sent to the user
    log()
  })
  return <>{children}</>
}
```

> **Good to know**:
>
> - `unstable_after()` will be executed even if the response didn't complete successfully. Including when an error is thrown or when `notFound()` or `redirect()` is called.
> - `unstable_after()` is a [dynamic function](/docs/app/building-your-application/rendering/server-components#dynamic-functions) that will opt a route into dynamic rendering. This behavior can be overridden with the [`export dynamic = "force-static"`](/docs/app/api-reference/file-conventions/route-segment-config#dynamic) segment config.
> - You can use React `cache` to deduplicate functions called inside `unstable_after()`.
> - [`cookies()`](/docs/app/api-reference/functions/cookies) cannot be set inside `unstable_after()` since the response has already been sent.
> - `unstable_after()` can be nested inside other `unstable_after()` calls.

## Parameters

- A callback function which will be executed after the response is finished.

## Returns

- `unstable_after()` does not return a value.

## Alternatives

The use case for `unstable_after()` is to process secondary tasks without blocking the primary response. It's similar to using the platform's [`waitUntil()`](https://vercel.com/docs/functions/functions-api-reference) or removing `await` from a promise, but with the following differences:

- **`waitUntil()`**: accepts a promise and enqueues a task to be executed during the lifecycle of the request, whereas `unstable_after()` accepts a callback that will be executed **after** the response is finished.
- **Removing `await`**: starts executing during the response, which uses resources. It's also not reliable in serverless environments as the function stops computation immediately after the response is sent, potentially interrupting the task.

We recommend using `unstable_after()` as it has been designed to consider other Next.js APIs and contexts.

## Serverless function duration

`unstable_after()` will run for the platform's default or configured max duration of a serverless function. If your platform supports it, you can configure the timeout limit using the [`maxDuration`](/docs/app/api-reference/file-conventions/route-segment-config#maxduration) route segment config.
